using System;
using System.IO;
using Microsoft.Win32.SafeHandles;

namespace PipeCSharp
{
    public class NamedPipeClient
    {
        public NamedPipeClient(string pipeName)
        {
            m_pipeName = pipeName;
        }

        ~NamedPipeClient()
        {
            Disconnect();
        }

        public static int IsServerAvailable(string pipeName)
        {
            return Win32Native.WaitNamedPipe(pipeName, Win32Native.NMPWAIT_USE_DEFAULT_WAIT);
        }

        public int IsServerAvailable()
        {
            return IsServerAvailable(m_pipeName);
        }

        public bool Connect()
        {

            m_pipe = Win32Native.CreateFile(m_pipeName, Win32Native.GENERIC_WRITE, 0, Win32Native.GetSecAttrs(FileShare.None), FileMode.Open, Win32Native.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);

            return m_pipe.IsInvalid;
        }

        public unsafe bool Write(KeyInfo keyInfo)
        {
            byte* data = (byte*)&keyInfo;
            int numBytesWritten;
            int result = Win32Native.WriteFile(m_pipe, data, sizeof(KeyInfo), out numBytesWritten, IntPtr.Zero);
            return result > 0 && numBytesWritten == sizeof(KeyInfo);
        }

        public void Disconnect()
        {
            if (m_pipe.IsInvalid)
            {
                m_pipe.Close();
                m_pipe = null;
            }
        }

        private readonly string m_pipeName;
        private SafeFileHandle m_pipe;
    }
}